package com.araaya.eslimsmobile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import com.araaya.eslimsmobile.R;
import com.araaya.eslimsmobile.db.DatabaseFunction;
import com.araaya.eslimsmobile.db.GPSLand;
import com.araaya.eslimsmobile.gps.MobileKmlWriter;
import com.araaya.eslimsmobile.util.ElandConstant;
import com.araaya.eslimsmobile.web.WebCaller;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class LandList extends ListActivity {

	private long landId;
	private String userName;
	private boolean webRes;
	private String kmlTxt = ElandConstant.ALERT_BTN_CREATEKML_STR;

	ListAdapter adapter;
	ArrayList<HashMap<String, String>> landList;

	private EditText txtSearch;
	int textlength=0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.land_list);

		// get the Web State
		webRes = getIntent().getExtras().getBoolean("web");
		if (webRes) {
			// call from web application
			landId = getIntent().getExtras().getLong("landId");
			userName = getIntent().getExtras().getString("userName");
			kmlTxt = ElandConstant.ALERT_BTN_ATTACHKML_STR;
		} else {
			kmlTxt = ElandConstant.ALERT_BTN_CREATEKML_STR;
		}

		txtSearch= (EditText) findViewById(R.id.txtSearch);

		landList = new ArrayList<HashMap<String, String>>();
		landList = loadLandList();

		if (landList.size() == 0) {
			finish();
			Toast.makeText(LandList.this, ElandConstant.NO_LAND_DB_STR,
					Toast.LENGTH_LONG).show();
		}

		adapter = new SimpleAdapter(this, landList, R.layout.land_list_view,
				new String[] { "landname" }, new int[] { R.id.item_title });

		setListAdapter(adapter);

		// on click the List
		final ListView lv = getListView();
		lv.setLongClickable(true);
		lv.setTextFilterEnabled(true);
		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				@SuppressWarnings("unchecked")
				final HashMap<String, String> o = (HashMap<String, String>) lv
						.getItemAtPosition(position);

				landListAlert(o.get("landname"), o.get("coordinates"));

			}

		});

		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
			public boolean onItemLongClick(AdapterView<?> parent, View v,
					int position, long id) {
				@SuppressWarnings("unchecked")
				final HashMap<String, String> o = (HashMap<String, String>) lv
						.getItemAtPosition(position);
				// Toast.makeText(getApplicationContext(), "Long",
				// Toast.LENGTH_LONG).show();
				deleteLandAlert("Delete or Rename Land ?",
						"Manage Land", "Yes", R.drawable.pencil, o.get("id"),
						position);
				return true;
			}
		});
		
		txtSearch.addTextChangedListener(new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				// TODO Auto-generated method stub
				String searchTxt=txtSearch.getText().toString();
				if(searchTxt!=null && searchTxt.length()>0){
					landList = loadLandListByLandName(searchTxt);

					/*if (landList.size() == 0) {
						Toast.makeText(LandList.this, "There Land Name not in the  database",
								Toast.LENGTH_LONG).show();
					}*/

					
				}else{
					landList = loadLandList();
				}
				adapter = new SimpleAdapter(LandList.this, landList, R.layout.land_list_view,
						new String[] { "landname" }, new int[] { R.id.item_title });

				setListAdapter(adapter);
				
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
				
			}
		});

	}
	
	private void refreshActivity(){
		this.finish();
		startActivity(getIntent());
	}
	
	private ArrayList<HashMap<String, String>> loadLandList() {

		DatabaseFunction databaseFunction = new DatabaseFunction(LandList.this);
		ArrayList<HashMap<String, String>> landList = new ArrayList<HashMap<String, String>>();

		List<GPSLand> gpsLands = new ArrayList<GPSLand>();
		gpsLands = databaseFunction.getAllGPSLands();
		if (gpsLands.size() > 0) {

			for (int i = 0; i < gpsLands.size(); i++) {
				GPSLand gland = gpsLands.get(i);
				HashMap<String, String> map = new HashMap<String, String>();
				if (gland != null) {
					map.put("id", "" + gland.getId());
					map.put("landname", gland.getLandName());
					map.put("coordinates", gland.getCoordinates());
					landList.add(map);
					Log.d("NAME==>", gland.getLandName());
					Log.d("MapNAME==>", map.get("landname"));
				}

			}

		}
		return landList;

	}
	
	private ArrayList<HashMap<String, String>> loadLandListByLandName(String landName) {

		DatabaseFunction databaseFunction = new DatabaseFunction(LandList.this);
		ArrayList<HashMap<String, String>> landList = new ArrayList<HashMap<String, String>>();

		List<GPSLand> gpsLands = new ArrayList<GPSLand>();
		gpsLands = databaseFunction.getGPSLandsByName(landName);
		if (gpsLands.size() > 0) {

			for (int i = 0; i < gpsLands.size(); i++) {
				GPSLand gland = gpsLands.get(i);
				HashMap<String, String> map = new HashMap<String, String>();
				if (gland != null) {
					map.put("id", "" + gland.getId());
					map.put("landname", gland.getLandName());
					map.put("coordinates", gland.getCoordinates());
					landList.add(map);
					Log.d("NAME==>", gland.getLandName());
					Log.d("MapNAME==>", map.get("landname"));
				}

			}

		}
		return landList;

	}

	private void removePointByPosition(int pos) {
		landList.remove(pos);

		//adapter.notifyAll();
		 ((BaseAdapter) adapter).notifyDataSetChanged();
	}

	private void landListAlert(final String landName, final String coordinate) {
		AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
		alt_bld.setMessage("")
				.setCancelable(false)
				.setPositiveButton("Show Map",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								/*Intent i = new Intent(getApplicationContext(),
										MyMapViewer.class);
								i.putExtra("coordinate", coordinate);
								startActivity(i);*/
								
								
							
								
								/*MobileKmlWriter kmlWriter = new MobileKmlWriter();
								String middlePoint=kmlWriter.getMiddlePoint(coordinate);
								long refNo=kmlWriter.getReferenceNo();
								
								Intent i = new Intent(getBaseContext(), WebHome.class);
								i.putExtra("coordinate", coordinate);
								i.putExtra("middlePoint", middlePoint);
								i.putExtra("refNo", refNo);
								startActivity(i);*/
								
								mapTypeViewAlert(coordinate);
								return;

							}
						})
				.setNegativeButton("Cancel",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								dialog.cancel();
								return;

							}
						})
				.setNeutralButton(kmlTxt,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								/*
								 * Toast.makeText(LandList.this, "" + landId,
								 * Toast.LENGTH_SHORT).show();
								 */

								if (webRes) {

									// String
									// URL="http://192.168.1.101:8080/eLand/mobile/MobileController?maction=kmlSave&kmlData=coordinate&landId="
									// + landId +
									// "&userName=orlm&password=password";
									// Log.d("Url", URL);
									try {
										// get The Kml Data
										MobileKmlWriter kmlWriter = new MobileKmlWriter();
										String kmlString = kmlWriter
												.writeKmlFile(coordinate);

										kmlLoginAlert(landId, userName,
												coordinate, kmlString);

									} catch (Exception e) {
										Log.d("Exception", e.getMessage());
									}

								} else {
									if (createFile(landName, coordinate)) {
										Toast.makeText(LandList.this,
												ElandConstant.CTRATE_KML_SUCCESS_STR, Toast.LENGTH_LONG)
												.show();
									} else {
										Toast.makeText(LandList.this,
												ElandConstant.CTRATE_KML_FAILD_STR,
												Toast.LENGTH_LONG).show();
									}
								}

								return;

							}
						});

		AlertDialog alert = alt_bld.create();
		// Title for AlertDialog
		// alert.setTitle("eLand Mobile");
		alert.setTitle(landName);
		// Icon for AlertDialog
		alert.setIcon(R.drawable.land);
		alert.show();

	}

	// save the kml file
	public boolean createFile(String landName, String allCordiante) {
		// Create Folder
		File folder = new File(Environment.getExternalStorageDirectory()
				.toString() + "/eLand/kml");
		folder.mkdirs();

		// Save the path as a string value
		String extStorageDirectory = folder.toString();
		//String filename = landName + ".kml";
		
		String oldfilename = landName + ".kml";
		String filename = oldfilename.replace("/","_");		
		
		// Create New file and name it
		File file = new File(extStorageDirectory, filename);

		FileOutputStream fos;
		// byte[] data = new String("Kusal").getBytes();

		MobileKmlWriter kmlWriter = new MobileKmlWriter();
		String kmlString = kmlWriter.writeKmlFile(allCordiante);
		if (kmlString != null) {
			byte[] data = kmlString.getBytes();

			try {
				fos = new FileOutputStream(file);
				fos.write(data);
				fos.flush();
				fos.close();
				return true;
			} catch (FileNotFoundException e) {
				return false;
				// handle exception
			} catch (IOException e) {
				return false;
				// handle exception
			}
		} else {
			return false;
		}

	}

	// call to web Server
	private String sendInvitation(String userName, String password,
			long landId, String coordinate, String kmlString) {
		String result = "";
		WebCaller caller = new WebCaller();

		// Add data to be send.
		ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
				3);
		nameValuePairs.add(new BasicNameValuePair("maction", "kmlSave"));
		nameValuePairs.add(new BasicNameValuePair("userName", userName));
		nameValuePairs.add(new BasicNameValuePair("password", password));
		nameValuePairs.add(new BasicNameValuePair("landId", "" + landId));
		nameValuePairs.add(new BasicNameValuePair("coordinate", coordinate));
		nameValuePairs.add(new BasicNameValuePair("kmlData", kmlString));

		result = caller.sendData(nameValuePairs);
		return result;
		// InputStream in = callService(newUrl);
		// InputStream in = caller.callService(url);

		/*
		 * JSONObject jsonResponse = null; if (result.equals("fa")) { //
		 * Log.d("NOtNull","NOtNull"); // Log.d("NOtNullVal",
		 * caller.convertStreamToString(in)); try { // jsonResponse = new //
		 * JSONObject(caller.convertStreamToString(in)); result =
		 * caller.convertStreamToString(in); return result;
		 * 
		 * } catch (Exception e) { // result =
		 * "Error : JSON Object couldn't be made"; Log.d("Exception",
		 * e.getMessage()); return null; } } else { // result =
		 * "Error : Service not returning result"; return null; }
		 */

	}

	private void kmlLoginAlert(final long landId, final String user,
			final String coordinate, final String kmlData) {

		// get prompts.xml view
		LayoutInflater li = LayoutInflater.from(LandList.this);
		View promptsView = li.inflate(R.layout.login_kml, null);

		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
				LandList.this);

		alertDialogBuilder.setView(promptsView);

		// user name
		/*
		 * final EditText userName = (EditText) promptsView
		 * .findViewById(R.id.editTextDialogUserName);
		 */

		// password
		final EditText password = (EditText) promptsView
				.findViewById(R.id.editTextDialogPassword);

		// userName.setText(user);
		// password.setText("password");

		// set dialog message
		alertDialogBuilder
				.setCancelable(false)
				.setMessage("Enter Password ")
				.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						// get user input and set it to result
						// String uName = userName.getText().toString();
						String pass = password.getText().toString();
						if (user.length() > 0 && pass.length() > 0) {
							/*
							 * Toast.makeText(LandList.this, uName + pass,
							 * Toast.LENGTH_LONG).show();
							 */
							Integer pic = R.drawable.ok;
							String resPost = sendInvitation(user, pass, landId,
									coordinate, kmlData);
							if (resPost.equals("success")) {
								resPost = ElandConstant.ATTACH_KML_SUCCESS_STR;
								pic = R.drawable.ok;
							} else {
								resPost = ElandConstant.ATTACH_KML_FAILD_STR;
								pic = R.drawable.wrong;
							}
							/*
							 * Toast.makeText(LandList.this, resPost,
							 * Toast.LENGTH_SHORT).show();
							 */
							displayAlert(resPost, "Attached Kml", "OK", pic);

						} else {
							Toast.makeText(LandList.this,
									ElandConstant.KML_LOGIN_ALERT,
									Toast.LENGTH_LONG).show();
						}

					}
				})
				.setNegativeButton("Cancel",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.cancel();
							}
						});

		// create alert dialog
		AlertDialog alertDialog = alertDialogBuilder.create();

		// show it
		alertDialog.show();

	}

	// Message Alert
	public void displayAlert(String message, String title, String btnTxt,
			Integer image) {

		AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
		alt_bld.setMessage(message)
				.setCancelable(false)
				.setPositiveButton(btnTxt,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								dialog.cancel();
								return;

							}
						});

		AlertDialog alert = alt_bld.create();
		// Title for AlertDialog
		alert.setTitle(title);
		// Icon for AlertDialog
		alert.setIcon(image);
		alert.show();
	}

	// Delete LAnd Alert
	public void deleteLandAlert(String message, String title, String btnTxt,
			Integer image, final String landId, final int pos) {

		AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
		alt_bld.setMessage(message)
				.setCancelable(false)
				.setPositiveButton("Delete",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								removePointByPosition(pos);
								DatabaseFunction databaseFunction = new DatabaseFunction(
										LandList.this);
								GPSLand gpsLand = new GPSLand();
								gpsLand.setId(Integer.parseInt(landId));
								databaseFunction.deleteGPSLand(gpsLand);
								return;

							}
						})
				.setNeutralButton("Rename",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								renameLandAlert(landId);
								return;

							}
						})
				.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						dialog.cancel();
						return;

					}
						});

		AlertDialog alert = alt_bld.create();
		// Title for AlertDialog
		alert.setTitle(title);
		// Icon for AlertDialog
		alert.setIcon(image);
		alert.show();
	}
	
	private void renameLandAlert(final String lId) {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("Rename Land");
		alert.setMessage("Enter New Name");
		
		final EditText input = new EditText(this);
		alert.setView(input);

		alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String name = input.getText().toString();
				DatabaseFunction dbf = new DatabaseFunction(LandList.this);
				GPSLand land = dbf.getGPSLand(Integer.parseInt(lId));
				land.setLandName(name);
				dbf.updateGPSLand(land);
				refreshActivity();
				//((BaseAdapter) adapter).notifyDataSetChanged();
				return;
			}
		});

		alert.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {
							dialog.cancel();
							return;
						}
					});
			
		alert.show();
	}
	
	private void mapTypeViewAlert(final String coordinate) {

		AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
		alt_bld.setMessage("Select Your Map Type")
				.setCancelable(false)
				.setPositiveButton("Show Map",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								Intent i = new Intent(getApplicationContext(),
										MyMapViewer.class);
								i.putExtra("coordinate", coordinate);
								startActivity(i);
								
								return;

							}
						})
				
				.setNeutralButton("Map With Area",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
							
								MobileKmlWriter kmlWriter = new MobileKmlWriter();
								String middlePoint=kmlWriter.getMiddlePoint(coordinate);
								long refNo=kmlWriter.getReferenceNo();
								
								Intent i = new Intent(getBaseContext(), WebHome.class);
								i.putExtra("coordinate", coordinate);
								i.putExtra("middlePoint", middlePoint);
								i.putExtra("refNo", refNo);
								startActivity(i);

								return;

							}
						})
						.setNegativeButton("Cancel",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								dialog.cancel();
								return;

							}
						});

		AlertDialog alert = alt_bld.create();
		alert.setTitle("View Map");
		// Icon for AlertDialog
		alert.setIcon(R.drawable.land);
		alert.show();

	}

}
